package com.zxy.supplier_system.server.service

import com.zxy.supplier_system.server.controller.DirectSaleClientController
import com.zxy.supplier_system.server.entity.DirectSaleClient
import com.zxy.supplier_system.server.repository.DirectSaleClientRepository
import com.zxy.supplier_system.server.repository.GoodsRepository
import com.zxy.supplier_system.server.repository.GoodsSummaryWithPrice
import com.zxy.supplier_system.server.repository.SystemServiceRepository
import com.zxy.supplier_system.server.utils.IntIdAndName
import com.zxy.supplier_system.server.utils.orElse404
import com.zxy.supplier_system.server.utils.toIntIdAndName
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
class DirectSaleClientService(
    private val directSaleClientRepository: DirectSaleClientRepository,
    private val systemServiceService: SystemServiceService,
    private val employeeOperateRecordService: EmployeeOperateRecordService,
    private val goodsRepository: GoodsRepository,
) {


    @Transactional(readOnly = true)
    fun queryDirectSaleClients(
        pageable: Pageable,
        queryDirectSaleClientsRequest: DirectSaleClientController.QueryDirectSaleClientsRequest
    ): Page<DirectSaleClientController.QueryDirectSaleClientsResponse> {
        return this.directSaleClientRepository.findAll(
            DirectSaleClientRepository.Specifications.fromQueryDirectSaleClient(queryDirectSaleClientsRequest)
                .and(
                    SystemServiceRepository.Specifications.systemServiceEquals(
                        { root -> root },
                        systemServiceService.getCurrentSystemService()
                    )
                ),
            pageable
        ).map { directSaleClient ->
            DirectSaleClientController.QueryDirectSaleClientsResponse(
                directSaleClient.name,
                directSaleClient.id,
                directSaleClient.orders.count {
                  it.submittedDateTime!=null
                },
                directSaleClient.orders.mapNotNull { it.submittedDateTime }.maxOrNull()
            )
        }
    }

    @Transactional
    fun updateDirectSaleClient(id: Int, updateDirectSaleClientRequest: DirectSaleClientController.UpdateDirectSaleClientRequest) {
        val directSaleClient = this.directSaleClientRepository.findByIdOrNull(id).orElse404()
        directSaleClient.name = updateDirectSaleClientRequest.name
        this.directSaleClientRepository.save(directSaleClient)
        this.employeeOperateRecordService.updateDirectSaleClient(directSaleClient)
    }

    @Transactional
    fun createDirectSaleClient(updateDirectSaleClientRequest: DirectSaleClientController.UpdateDirectSaleClientRequest):Int {
        val directSaleClient = this.directSaleClientRepository.save(DirectSaleClient().apply {
            name = updateDirectSaleClientRequest.name
            systemService = systemServiceService.getCurrentSystemService()
        })
        this.employeeOperateRecordService.createDirectSaleClient(directSaleClient)
        return directSaleClient.id
    }

    @Transactional
    fun deleteDirectSaleClient(id: Int) {
        this.directSaleClientRepository.deleteById(id)
    }


    fun getAllDirectSaleClients(): List<IntIdAndName> {
        return this.directSaleClientRepository.findAllBySystemService(systemServiceService.getCurrentSystemService()).map {
            IntIdAndName(it.id, it.name)
        }
    }

    @Transactional(readOnly = true)
    fun getDirectSaleClientDetail(id: Int): DirectSaleClientDetail {
        return with(
            this.directSaleClientRepository.findByIdAndSystemService(id, systemServiceService.getCurrentSystemService())
                .orElse404()
        ) {
            DirectSaleClientDetail(id, name)
        }
    }

    fun queryDirectSaleClientSummary(keyword: String?, pageable: Pageable): Page<IntIdAndName> {
        return this.directSaleClientRepository.findAll(DirectSaleClientRepository.Specifications.nameContains(keyword),pageable).map {
            it.toIntIdAndName()
        }
    }

    data class DirectSaleClientDetail(
        val id: Int,
        val name: String,
    )

    @Transactional(readOnly = true)
    fun findAllGoodsWithHistoryOrder(id: Int): List<GoodsSummaryWithPrice> {
        return this.goodsRepository.findAllWithRememberedDirectSalePrice(id)
    }

}
